import uuid

import requests
from functools import wraps


def refresh_csrf_token(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        response = func(self, *args, **kwargs)

        # 从响应头中获取CSRF令牌
        csrf_token = response.headers.get('X-Harbor-Csrf-Token')
        if csrf_token:
            # 更新会话头部
            self.session.headers.update({
                'X-Harbor-Csrf-Token': csrf_token,
            })

        return response

    return wrapper


class HarborClient:
    def __init__(self, base_url: str, authorization: str, verify_ssl: bool = True):
        self.base_url = base_url.rstrip('/')
        self.authorization = authorization
        self.session = requests.Session()

        self.session.verify = verify_ssl
        self.session.headers.update({
            'Authorization': self.authorization,
        })
        # 调用两次来确保csrf_token被赋值
        self.check_health()
        self.check_health()

    @refresh_csrf_token
    def check_health(self):
        url = f"{self.base_url}/health"
        return self.session.get(url)

    @refresh_csrf_token
    def create_project(self, name: str, public: bool):
        url = f"{self.base_url}/projects/"
        body = {
            "project_name": name,
            "public": public,
        }
        return self.session.post(url, json=body)

    @refresh_csrf_token
    def create_robot_account(self, project_name: str):
        url = f"{self.base_url}/robots/"
        body = {
            "name": str(uuid.uuid4())[:8],
            "description": "Project puller. Created for image buyer.",
            "level": "project",
            "duration": -1,
            "permissions": [
                {
                    "access": [
                        {
                            "resource": "repository",
                            "action": "pull",
                            "effect": None
                        }
                    ],
                    "kind": "project",
                    "namespace": project_name,
                }
            ]
        }
        return self.session.post(url, json=body)
